package impl

import (
	"context"
	"errors"
	"fmt"

	"gitee.com/hexug/devcloud/cmdb/apps/resource"
	"gitee.com/hexug/devcloud/cmdb/apps/secret"
	"gitee.com/hexug/devcloud/cmdb/common/logger"
	"gitee.com/hexug/devcloud/cmdb/common/validate"
	"gitee.com/hexug/devcloud/cmdb/provider/tengxun"
)

func (i *implServer) CreateSecret(ctx context.Context, in *secret.CreateSecretRequest) (*secret.Secret, error) {
	if err := validate.V().Struct(in); err != nil {
		logger.L().Errorf("数据校验出错：%s", err.Error())
		return nil, err
	}
	scet := secret.NewSecret(in)
	//加密
	scet.EncryptAPISecret(secret.EncryptKey)
	//保存到数据库
	err := i.
		db.
		WithContext(ctx).
		Table("secrets").
		Save(struct {
			*secret.Meta
			*secret.CreateSecretRequest
		}{
			scet.Meta,
			scet.Spec,
		}).
		Error
	if err != nil {
		logger.L().Errorw(err.Error())
		return nil, err
	}
	scet.Spec.Desense()
	return scet, nil
}
func (i *implServer) QuerySecret(ctx context.Context, in *secret.QuerySecretRequest) (*secret.SecretSet, error) {
	if err := validate.V().Struct(in); err != nil {
		logger.L().Errorf("数据校验出错：%s", err.Error())
		return nil, err
	}
	if in.PageSize <= 0 || in.PageSize >= 20 {
		in.PageSize = 5
	}
	if in.PageNumber <= 0 || in.PageNumber >= 10 {
		in.PageSize = 1
	}
	ss := secret.NewSecretSet()
	sset := []*struct {
		*secret.Meta
		*secret.CreateSecretRequest
	}{}
	err := i.
		db.
		WithContext(ctx).
		Table("secrets").
		Order("create_at desc").
		Offset(int(in.PageSize * (in.PageNumber - 1))).
		Limit(int(in.PageSize)).Find(&sset).Error
	if err != nil {
		logger.L().Errorf("查询出错：%s", err.Error())
		return nil, err
	}
	for _, se := range sset {
		s := secret.New()
		s.Meta = se.Meta
		s.Spec = se.CreateSecretRequest
		s.Spec.Desense()
		ss.Add(s)
	}
	err = i.
		db.
		WithContext(ctx).
		Table("secrets").
		Count(&ss.Total).Error
	if err != nil {
		logger.L().Errorf("查询出错：%s", err.Error())
		return nil, err
	}
	return ss, nil
}
func (i *implServer) DescribeSecret(ctx context.Context, in *secret.DescribeSecretRequest) (*secret.Secret, error) {
	if err := validate.V().Struct(in); err != nil {
		logger.L().Errorf("数据校验出错：%s", err.Error())
		return nil, err
	}
	sc := secret.New()
	err := i.
		db.
		WithContext(ctx).
		Table("secrets").
		Where("id=?", in.Id).First(&struct {
		*secret.Meta
		*secret.CreateSecretRequest
	}{
		sc.Meta,
		sc.Spec,
	}).Error
	if err != nil {
		logger.L().Errorf("查询出错：%s", err.Error())
		return nil, err
	}
	return sc, nil
}

// 同步数据
func (i *implServer) SyncResource(ctx context.Context, in *secret.DescribeSecretRequest) error {
	if err := validate.V().Struct(in); err != nil {
		logger.L().Errorf("数据校验出错：%s", err.Error())
		return err
	}
	//获取api和key
	ss, err := i.DescribeSecret(ctx, in)
	if err != nil {
		return err
	}
	if err := ss.DecryptAPISecret(secret.EncryptKey); err != nil {
		logger.L().Errorf("解密出错：%s", err.Error())
		return err
	}
	switch ss.Spec.Provider {
	case secret.PROVIDER_TENCENT_CLOUD:
		c := tengxun.NewTencentClient(ss.Spec.ApiId, ss.Spec.ApiSecret)
		c.SetResourceHandleHook(func(ctx context.Context, r *resource.Resource) {
			fmt.Printf("%+v", i.rs)
			_, err := i.rs.Put(ctx, r)
			if err != nil {
				logger.L().Errorf("同步数据时保存出错：%s", err.Error())
			}
		})
		if err := c.SyncHost(context.Background()); err != nil {
			logger.L().Errorf("同步数据出错：%s", err.Error())
			return err
		}
	default:
		return errors.New("尚未实现该供应商")
	}
	return nil
}
